/*
 * FtpAdapter.cpp
 *
 *  Created on: Nov 10, 2012
 *      Author: Scorpion
 */

#include "FtpAdapter.h"
#include <assert.h>
namespace centny {

FtpAdapter::FtpAdapter() {
}

FtpAdapter::~FtpAdapter() {
}
vector<FInfo*> FtpAdapter::subs(FInfo* parent) {
	vector<FInfo*> fis;
	CurlBuilder curl;
	curl.setURL(this->rurl + "/" + parent->cwd + "/");
	if (this->usrpwd.size()) {
		curl.setUsrPwd(this->usrpwd);
	}
	curl.setWriteCallback(&defaultStreamWriteCb, &curl.buf);
	const char* prs = curl.perform();
	if (prs) {
		printf("require subs fail:%s\n", prs);
	} else {
		fis = this->convert(parent, curl.buf);
	}
	return fis;
}
FInfo* FtpAdapter::root() {
	this->fre();
	FInfo *fi = new NetFInfo(this, 0);
	fi->cwd = "/";
	fi->type = 'd';
	this->addToMap(fi);
	return fi;
}
vector<FInfo*> FtpAdapter::convert(FInfo* parent, stringstream& buf) {
	vector<FInfo*> fis;
	while (!buf.eof()) {
		string line;
		std::getline(buf, line);
		if (line.length() < 1) {
			continue;
		}
		fis.push_back(this->convertOne(parent, line));
	}
	return fis;
}
FInfo* FtpAdapter::convertOne(FInfo* parent, string line) {
	FInfo *fi = new NetFInfo(this, (NetFInfo*) parent);
	string tmp;
	stringstream ss(line);
	ss >> tmp;
	fi->type = tmp.at(0);
	ss >> tmp >> tmp >> tmp >> tmp;
	fi->size = atol(tmp.c_str());
	struct tm cct;
	cct.tm_mon = 0;
	ss >> tmp;
	for (int i = 0; i < 12; i++) {
		if (tmp == string(MONTHES[i])) {
			cct.tm_mon = i;
			break;
		}
	}
	ss >> tmp;
	cct.tm_mday = atol(tmp.c_str());
	ss >> tmp;
	if (tmp.length() == 5) {
		cct.tm_hour = atol(tmp.substr(0, 1).c_str());
		cct.tm_min = atol(tmp.substr(3, 4).c_str());
	}
	ss >> tmp;
	fi->name = tmp;
	fi->mtime = (((cct.tm_mon + 1) * 30 + cct.tm_mday) * 24 + cct.tm_hour) * 60
			+ cct.tm_min;
	fi->parent = parent;
	string cwd = parent->cwd + "/" + fi->name;
	replaceAll(cwd, "//", "/");
	replaceAll(cwd, "///", "/");
	fi->cwd = cwd;
	this->addToMap(fi);
	return fi;
}
const char* FtpAdapter::upload(FInfo* fi, string lf, string name) {
	if (!fi->isDir()) {
		return "is not folder";
	}
	CurlBuilder curl;
	curl.setUsrPwd(this->usrpwd);
	curl.setUpload(1L);
	curl.setURL(this->rurl + "/" + fi->cwd + "/" + name);
	curl.setFile(lf);
	curl.setReadCallback();
	return curl.perform();
}
const char* FtpAdapter::upload(FInfo* fi, istream& is, string name) {
	if (!fi->isDir()) {
		return "is not folder";
	}
	CurlBuilder curl;
	curl.setUsrPwd(this->usrpwd);
	curl.setUpload(1L);
	curl.setURL(this->rurl + "/" + fi->cwd + "/" + name);
	curl.setReadCallback(&defaultStreamReadCb, &is);
	return curl.perform();
}
const char* FtpAdapter::download(FInfo* fi, string lf) {
	if (fi->isDir()) {
		return "is not file";
	}
	CurlBuilder curl;
	curl.setUsrPwd(this->usrpwd);
	curl.setUpload(0L);
	curl.setURL(this->rurl + "/" + fi->cwd);
	curl.setFile(lf);
	curl.setWriteCallback();
	return curl.perform();
}
const char* FtpAdapter::download(FInfo* fi, ostream& os) {
	if (fi->isDir()) {
		return "is not file";
	}
	CurlBuilder curl;
	curl.setUsrPwd(this->usrpwd);
	curl.setUpload(0L);
	curl.setURL(this->rurl + "/" + fi->cwd);
	curl.setWriteCallback(&defaultStreamWriteCb, &os);
	return curl.perform();
}
NetFInfo* FtpAdapter::mkdir(FInfo* fi, string name) {
	if (fi->isDir()) {
		return 0;
	}
	CurlBuilder curl;
	curl.setUsrPwd(this->usrpwd);
	curl.setUpload(0L);
	curl.setURL(this->rurl + "/" + fi->cwd);
	curl.appHeader("MKD " + name);
	const char* msg = curl.perform();
	if (msg) {
		return 0;
	} else {
		NetFInfo *nfi = new NetFInfo(this, (NetFInfo*) fi);
		nfi->name = name;
		nfi->type = 'd';
		nfi->cwd = fi->cwd + name + "/";
		this->addToMap(nfi);
		return nfi;
	}
}
} /* namespace centny */
